package org.framework.lazy.cloud.network.heartbeat.protocol.filter;

import io.netty.channel.ChannelPipeline;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.codec.socksx.SocksPortUnificationServerHandler;
import io.netty.handler.codec.socksx.v5.*;
import org.framework.lazy.cloud.network.heartbeat.common.adapter.ChannelTypeAdapter;
import org.framework.lazy.cloud.network.heartbeat.common.advanced.HandleChannelTypeAdvanced;
import org.framework.lazy.cloud.network.heartbeat.common.filter.DebugChannelInitializer;
import org.framework.lazy.cloud.network.heartbeat.protocol.auth.NettyPasswordAuth;
import org.framework.lazy.cloud.network.heartbeat.protocol.handler.*;
import org.framework.lazy.cloud.network.heartbeat.protocol.properties.ProtocolProxyProperties;
import org.springframework.stereotype.Component;

import java.util.List;

/**
 * description
 *
 * @author 吴佳伟
 * @date 2023/09/13 10:26
 */
@Component
public class NettyTcpProxyFilter extends DebugChannelInitializer<SocketChannel> {
    private final List<HandleChannelTypeAdvanced> handleChannelTypeAdvancedList;
    private final NettyPasswordAuth nettyPasswordAuth;
    private final ProtocolProxyProperties protocolProxyProperties;

    public NettyTcpProxyFilter(List<HandleChannelTypeAdvanced> handleChannelTypeAdvancedList, NettyPasswordAuth nettyPasswordAuth, ProtocolProxyProperties protocolProxyProperties) {
        this.handleChannelTypeAdvancedList = handleChannelTypeAdvancedList;
        this.nettyPasswordAuth = nettyPasswordAuth;
        this.protocolProxyProperties = protocolProxyProperties;
    }

    @Override
    protected void initChannel0(SocketChannel ch) throws Exception {
        ChannelPipeline pipeline = ch.pipeline();
        // 类型处理器适配器
        ChannelTypeAdapter channelTypeAdapter = new ChannelTypeAdapter(handleChannelTypeAdvancedList);
//
//        //添加 SOCKS 协议统一处理器
//        pipeline.addLast(new SocksPortUnificationServerHandler());

        //socks5响应最后一个encode
        pipeline.addLast(Socks5ServerEncoder.DEFAULT);
        // 初始化连接
        pipeline.addLast(new Socks5InitialRequestDecoder());
        pipeline.addLast(new NettySocks5InitialRequestHandler(protocolProxyProperties, nettyPasswordAuth));

        if (protocolProxyProperties.getAuthentication()) {
            // 认证
            pipeline.addLast(new Socks5PasswordAuthRequestDecoder());
            pipeline.addLast(new NettySocks5PasswordAuthRequestInboundHandler(nettyPasswordAuth));
        }

        // 连接请求
        pipeline.addLast(new Socks5CommandRequestDecoder());
        pipeline.addLast(new NettySocks5CommandRequestHandler(channelTypeAdapter));


    }
}